/*
* @Date: 2021/3/28
* @Author: XueChengwu <xuechengwu@erayt.com>
* @Copyright: 2015-2019 Erayt, Inc.
* @Description: If you have some questions, please contact: xuechengwu@erayt.com.
*/
import React from 'react';
import VerticalDivider from '@/components/VerticalDivider';
import HorizontalDivider from '@/components/HorizontalDivider';
import Style from './Style';
import { Tabs } from 'antd';
import $ from 'jquery';
import 'jquery-ui';
import ReactDOM from 'react-dom';
import Icon from '@/components/Icon';
import './index.scss';
import Viewer from './Viewer';
import FileViewer from './FileViewer';
import Component from './Component';
import { get, post } from '../../../../utils/http';
import { getParams, randstr } from '../../../../utils/common';
import Project from "../cls/Project";

const TabPane = Tabs.TabPane;
// const { remote } = window.require('electron');
export default class extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      propsValue: {},
      styleValue: {},
      component: '',
      componentId: '',
      sourceData: [],
      projectName: '',
      pages: [],
      modals: [],
      widgets: [],
    }
  }

  componentWillMount () {
    const params = getParams();
    get('/api/projectDetail', {
      shortcode: params.c,
    }).then((res) => {
      if (Number(res.code) === 0) {
        const { detail } = res.data;
        this.project = new Project(detail);
        this.setState({
          pages: this.project.pages.map(vo => ({ title: vo.name, key: vo.key })),
          modals: this.project.modals.map(vo => ({ title: vo.name, key: vo.key })),
          widgets: this.project.widgets.map(vo => ({ title: vo.name, key: vo.key })),
          projectName: this.project.name,
        });
      } else {
        this.project = new Project({
          name: 'test',
          pages: [{
            title: 'page1',
            key: randstr(),
          }],
          modals: [],
          widgets: [],
        });
        this.setState({
          pages: this.project.pages.map(vo => ({ title: vo.name, key: vo.key })),
          modals: this.project.modals.map(vo => ({ title: vo.name, key: vo.key })),
          widgets: this.project.widgets.map(vo => ({ title: vo.name, key: vo.key })),
          projectName: this.project.name,
        }, () => {
          post('/api/saveProject', {
            shortcode: params.c,
            body: this.project.toString(),
          });
        });
      }
    });
  }

  parse(doc, index = 0) {
    if (!doc) {
      return null;
    }
    const doms = doc.childNodes;
    if (doms.length === 0) {
      return null;
    }
    const virtuals = [];
    for (let i = 0; i < doms.length; i++) {
      const $target = $(doms[i]);
      let vdom = null;
      if ($target.hasClass('view-item-box')) {
        const id = $target.attr('id');
        const componentName = $target.attr('data-component');
        vdom = {
          key: id,
          label: componentName,
          children: this.parse(doms[i], index + 1),
        };
      } else {
        vdom = this.parse(doms[i], index);
      }
      if (vdom !== null) {
        virtuals.push(vdom);
      }
    }
    return virtuals.length === 0 ? null : virtuals.length === 1 ? virtuals[0] : virtuals;
  }

  onSortableUpdate = (e, t) => {
    const $dom = $(t.item[0]);
    $dom.empty();
    $('.view-item-box.active').removeClass('active');
    const container = document.createElement('div');
    const $container = $(container);
    const drag = document.createDocumentFragment();
    ReactDOM.render(<Icon type="move" className="drag" />, drag);
    container.classList = 'view-item-box cbox active';
    this.activeDOM = container;
    $dom.append($container);
    $dom.append(drag);
    const componentId = XUE.getGuid();
    const componentName = $dom.attr('data-component');
    $container.attr('id', componentId);
    $container.attr('data-component', componentName);
    const component = window.components[componentName];
    const componentDescription = window.descriptions || {};
    let props = {};
    if (componentDescription[componentName]) {
      const desc = componentDescription[componentName];
      const { display = 'block' } = desc;
      $dom.css('display', display);
      for (let i = 0; i < desc.props.length; i++) {
        const prop = desc.props[i];
        props[prop.key] = prop.defaultValue;
      }
      props = Object.assign({}, props, componentDescription[componentName].defaultProps || {});
      if (componentDescription[componentName].childParamer) {
        componentDescription[componentName]
          .childParamer()
          .then(param => {
            console.log(1112);
            if (componentDescription[componentName].childRender) {
              props.children = componentDescription[componentName].childRender(param);
            }
            const reactDom = React.createElement(component, props);
            !window.form ? window.form = { [componentId]: reactDom } : window.form[componentId] = reactDom;
            ReactDOM.render(reactDom, container);
            $('.sortable').sortable({
              connectWith: '.sortable',
              handle: '.drag',
              update: this.onSortableUpdate,
            });
            console.log(111,this.parse(document.getElementById('viewer-box-designer-window')))
            this.setState({
              sourceData: this.parse(document.getElementById('viewer-box-designer-window')),
            });
          }).catch((err) => {
          console.log(err);
          $dom.remove();
        });
      } else {
        const reactDom = React.createElement(component, props);
        !window.form ? window.form = { [componentId]: reactDom } : window.form[componentId] = reactDom;
        ReactDOM.render(reactDom, container);
        $('.sortable').sortable({
          connectWith: '.sortable',
          handle: '.drag',
          update: this.onSortableUpdate,
        });
      }
    } else {
      const reactDom = React.createElement(component, props);
      !window.form ? window.form = { [componentId]: reactDom } : window.form[componentId] = reactDom;
      ReactDOM.render(reactDom, container);
      $('.sortable').sortable({
        connectWith: '.sortable',
        handle: '.drag',
        update: this.onSortableUpdate,
      });
    }
    console.log(this.parse(document.getElementById('viewer-box-designer-window')))
    this.setState({
      propsValue: {
        ...props,
        children: undefined,
      },
      component: componentName,
      componentId,
      sourceData: this.parse(document.getElementById('viewer-box-designer-window')),
    });
  }

  onPropsChange  = (propsDesc) => {
    const { key, value, uid, component } = propsDesc;
    const reactDom = window.form[uid];
    const { props } = reactDom;
    const targetDom = React.createElement(window.components[component], {
      ...props,
      [key]: value === '' ? undefined : value,
    });
    window.form[uid]  = targetDom;
    ReactDOM.render(targetDom, this.activeDOM);
    this.setState({
      componentId: uid,
      propsValue: {
        ...props,
        [key]: value,
        children: undefined,
      },
      component,
    });
  }

  componentDidMount() {
    $('.sortable' ).sortable({
      connectWidth:'.sortable',
      handle:'.drag',
      update: this.onSortableUpdate,
    });
    $('.components-box .draggable').draggable({
      connectToSortable: '.sortable',
      helper: 'clone',
      handle:'.drag',
    });
    $(document).on('click', '.view-item-box.cbox', e => {
      e.stopPropagation();
      const $target = $(e.currentTarget);
      this.activeDOM = e.currentTarget;
      $('.view-item-box.active').removeClass('active');
      const componentName = $target.attr('data-component');
      const componentId = $target.attr('id');
      $target.addClass('active');
      const component = window.form[componentId];
      const { props } = component;
      this.setState({
        propsValue: {
          ...props,
          children: undefined,
        },
        component: componentName,
        componentId,
      });
    });
  }

  onStyleChange = (options) => {
    const { key, value, uid, component } = options;
    const reactDom = window.form[uid];
    const { props } = reactDom;
    let { style = {} } = props;
    let targetStyle = { ...style };
    targetStyle[XUE.toHump(key)] = value;
    $(`#${uid}`).css(key, value);
    $(`#${uid}`).parent().css(key, value);
    const targetDom = React.createElement(window.components[component], {
      ...props,
      style: {
        ...targetStyle
      },
    });
    console.log('target dom ===>', targetDom);
    window.form[uid]  = targetDom;
    ReactDOM.render(targetDom, this.activeDOM);
    this.setState({
      componentId: uid,
      styleValue: {
        ...targetStyle,
      },
      component,
    });
  }

  onViewSource = () => {
    const { form = {}, functions = {} } = window;
    let components = new Set();
    for (let key in form) {
      const $target = $(`#${key}`);
      const componentName = $target.attr('data-component');
      components.add(componentName);
    }
    components = [...components];
    let funcs = [];
    for (let key in functions) {
      funcs.push(functions[key]);
    }
    let reactDom = XUE.generateReactComponent(
      document.getElementById('viewer-box-designer-window'),
      0,
      {
        target: document.getElementById('viewer-box-designer-window'),
        components: window.form,
        styles: {},
        functions: [],
        descriptions: window.components,
      }
    );
    if (reactDom instanceof Array) {
      reactDom = <React.Fragment>{reactDom}</React.Fragment>
    }
    const renderSource = XUE.generateReactCode(reactDom, 0);
    const code = XUE.codeGenerator({
      components,
      functions: funcs,
      datas: window.datas,
      styles: [],
      renderSource,
    });
    const dialog = XUE.showDialog({
      title: '代码预览',
      onCancel() {
        dialog.close();
      },
      onOk() {
        dialog.close();
      }
    }, (
      <Code content={code} type={1} />
    ));

    // const win = remote.getCurrentWindow();
    // XUE.win.openWin({
    //   path: 'http://localhost:8899/code.html',
    //   winConfig: {
    //     parent: win.winId,
    //     modal: true,
    //     frame: false,
    //     show: false,
    //     width: 800,
    //     height: 800,
    //     disableHtmlFullscreenWindowResize: true,
    //     resizable: true,
    //     webPreferences: {
    //       nodeIntegration: true,
    //     },
    //   },
    // });
    // setTimeout(() => {
    //   XUE.win.emit('ipc:code:view', code, win.winId);
    // }, 1000);
  }

  render() {
    const {
      propsValue, component = '', componentId,
      sourceData, projectName = '',
    } = this.state;
    return (
      <div className="form-designer-box">
        <FileViewer
          projectName={projectName}
          pages={[{
            title: 'page1',
            key: 'page-page1',
          }]}
        />
        <Viewer />
        <VerticalDivider style={{width: 3, background: '#454545'}} />
        <Tabs type="card">
          <TabPane tab="组件" key="components">
            <Component />
          </TabPane>
          <TabPane tab="标签" key="html">
            <p>Content of Tab Pane 2</p>
            <p>Content of Tab Pane 2</p>
            <p>Content of Tab Pane 2</p>
          </TabPane>
          <TabPane tab="属性" key="props">

          </TabPane>
          <TabPane tab="样式" key="style">
            <Style
              onStyleChange={this.onStyleChange}
            />
          </TabPane>
          <TabPane tab="数据" key="data">

          </TabPane>
        </Tabs>
      </div>
    );
  }
}
